import { WebSocketServer as WSServer } from 'ws';
import http from 'http';

export class WebSocketServer {
  constructor() {
    this.clients = new Set();
    this.server = null;
    this.wss = null;
  }

  start(port) {
    // 创建HTTP服务器用于WebSocket升级
    this.server = http.createServer();
    
    // 创建WebSocket服务器
    this.wss = new WSServer({ 
      server: this.server,
      path: '/ws'
    });

    this.wss.on('connection', (ws, req) => {
      const clientId = this.generateClientId();
      ws.clientId = clientId;
      ws.connectedAt = Date.now();
      ws.subscriptions = new Set();
      
      this.clients.add(ws);
      console.log(`📡 WebSocket客户端连接: ${clientId}`);
      
      // 发送连接确认消息
      this.sendToClient(ws, {
        type: 'connection',
        data: { 
          clientId: clientId,
          message: '连接成功'
        },
        timestamp: Date.now()
      });

      // 处理客户端消息
      ws.on('message', (message) => {
        try {
          const data = JSON.parse(message.toString());
          this.handleClientMessage(ws, data);
        } catch (error) {
          console.error('❌ 解析WebSocket消息失败:', error);
          this.sendError(ws, '无效的消息格式');
        }
      });

      // 处理连接关闭
      ws.on('close', () => {
        this.clients.delete(ws);
        console.log(`📡 WebSocket客户端断开: ${clientId}`);
      });

      // 处理连接错误
      ws.on('error', (error) => {
        console.error(`❌ WebSocket客户端错误 (${clientId}):`, error);
        this.clients.delete(ws);
      });
    });

    // 启动HTTP服务器
    return new Promise((resolve, reject) => {
      this.server.listen(port, '0.0.0.0', (error) => {
        if (error) {
          reject(error);
        } else {
          console.log(`📡 WebSocket服务器启动: ws://0.0.0.0:${port}/ws (可通过 ws://localhost:${port}/ws 访问)`);
          resolve();
        }
      });
    });
  }

  stop() {
    if (this.wss) {
      // 关闭所有客户端连接
      this.clients.forEach(client => {
        try {
          client.close();
        } catch (error) {
          console.error('❌ 关闭WebSocket客户端失败:', error);
        }
      });
      this.clients.clear();
      
      this.wss.close();
      this.wss = null;
    }

    if (this.server) {
      this.server.close();
      this.server = null;
    }

    console.log('📡 WebSocket服务器已停止');
  }

  // 处理客户端消息
  handleClientMessage(ws, message) {
    switch (message.type) {
      case 'ping':
        this.sendToClient(ws, {
          type: 'pong',
          data: { timestamp: Date.now() },
          timestamp: Date.now()
        });
        break;
        
      case 'subscribe':
        // 客户端订阅特定类型的消息
        if (message.data?.eventType) {
          ws.subscriptions.add(message.data.eventType);
          console.log(`📡 客户端 ${ws.clientId} 订阅事件: ${message.data.eventType}`);
        }
        break;
        
      case 'unsubscribe':
        // 客户端取消订阅
        if (message.data?.eventType) {
          ws.subscriptions.delete(message.data.eventType);
          console.log(`📡 客户端 ${ws.clientId} 取消订阅事件: ${message.data.eventType}`);
        }
        break;
        
      default:
        this.sendError(ws, '未知的消息类型');
    }
  }

  // 广播新的HTTP交互记录
  broadcastTransaction(transaction) {
    const message = {
      type: 'transaction',
      data: transaction,
      timestamp: Date.now()
    };
    
    this.broadcast(message);
    console.log(`📡 广播事务: ${transaction.request.method} ${transaction.request.url}`);
  }

  // 广播规则匹配事件
  broadcastRuleMatched(ruleId, ruleName, transaction) {
    const message = {
      type: 'rule_matched',
      data: {
        ruleId,
        ruleName,
        transaction
      },
      timestamp: Date.now()
    };
    
    this.broadcast(message);
    console.log(`📡 广播规则匹配: ${ruleName}`);
  }

  // 广播代理状态变化
  broadcastProxyStatus(status) {
    const message = {
      type: 'proxy_status',
      data: status,
      timestamp: Date.now()
    };
    
    this.broadcast(message);
  }

  // 广播错误信息
  broadcastError(error, details) {
    const message = {
      type: 'error',
      data: {
        error,
        details
      },
      timestamp: Date.now()
    };
    
    this.broadcast(message);
  }

  // 向所有客户端广播消息
  broadcast(message) {
    const messageStr = JSON.stringify(message);
    
    this.clients.forEach(client => {
      try {
        // 检查客户端是否订阅了此类型的消息
        if (client.readyState === 1 && // WebSocket.OPEN
            (!client.subscriptions.size || client.subscriptions.has(message.type))) {
          client.send(messageStr);
        }
      } catch (error) {
        console.error(`❌ 发送消息给客户端失败:`, error);
        // 移除断开的客户端
        this.clients.delete(client);
      }
    });
  }

  // 向特定客户端发送消息
  sendToClient(ws, message) {
    try {
      if (ws.readyState === 1) { // WebSocket.OPEN
        ws.send(JSON.stringify(message));
      }
    } catch (error) {
      console.error(`❌ 发送消息给客户端失败:`, error);
      this.clients.delete(ws);
    }
  }

  // 向客户端发送错误消息
  sendError(ws, error) {
    this.sendToClient(ws, {
      type: 'error',
      data: { error },
      timestamp: Date.now()
    });
  }

  // 生成客户端ID
  generateClientId() {
    return `client-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
  }

  // 获取连接的客户端数量
  getClientCount() {
    return this.clients.size;
  }

  // 获取所有客户端信息
  getClientsInfo() {
    return Array.from(this.clients).map(client => ({
      clientId: client.clientId || 'unknown',
      connectedAt: client.connectedAt || 0,
      subscriptions: client.subscriptions ? Array.from(client.subscriptions) : []
    }));
  }
} 